<template>
<div @contextmenu="onContextMenu"  @click.stop="onClickMap" class="map">

  <div @click="changeScene" class="btn">
      切换
  </div>
<!-- 右键菜单部分 -->
  <div
      :style="{
          top: menuSide.top,
          left:menuSide.left
      }"
      :class="{
     menus:true,
    'show-menu': showMenu && menus.length > 1
  }">
      <div class="menu">
        <ul>
          <template v-for="(item,index) in menus" :key="index">
            <li :class="{
              'a-menu':true,
              'active-menu': index === menus.length - 1
            }"  @click="onClickMenu(item,index)" >
              {{ item.name}}
            </li>
          </template>

        </ul>
  </div>
</div>
</div>
</template>
<script setup>
import {
  UseCreateScene,
  UseCreateCamera,
  UseCreateRenderer,
  UseCreateGUIHelp,
  UseCreateControls,
  UseCreateRaycaster
} from "@/views/map/utils/useCreateScene.js";
import {onMounted, reactive, ref} from "vue";
import SceneManager from "@/views/map/utils/sceneManager.js";
import {UseCreateArea, UseCreateCubeForTest} from "@/views/map/utils/useCreateArea.js";

let scenenManager =  new SceneManager();
let scene1 =  null;
let scene2 = null;
let listenDom = null;

const showMenu = ref(false);
const menuSide = reactive({
    top:'0px',
    left:'0px'
})
onMounted(()=>{
  iniScene();
  listenDom = document.querySelector(".map");
});

const menus = ref([])

/**
 * 显示右键菜单
 * @param $event
 */
function onContextMenu($event){

  let scene = scenenManager.getCurrentSceneName();
  if (scene === scene1 ){
    let scenec = scenenManager.getScene(scene1);
    let camera = scenenManager.getCamera(scene1);
    UseCreateRaycaster($event,camera,scenec.userData.listenMesh,listenDom,async currentActive=>{
      if(currentActive?.length === 0){
        //显示右键菜单
        showMenu.value = true;
        menuSide.top = `${$event.clientX}px`;
        menuSide.left = `${$event.clientX}px` ;
        return;
      }
      // 显示地图悬浮提示弹窗

    });

  }

}

/*
 * @description: 初始化场景1
 * @returns {Promise<void>}
 */
async function  initScene1(){
  let renderer = UseCreateRenderer(document.querySelector(".map"));
  let camera = UseCreateCamera(document.querySelector(".map"))
  let controls = UseCreateControls(camera,renderer);
  let scene = UseCreateScene();
  let china = await UseCreateArea(10000,'中国')
   scene.add(china);
   scene1 =  scenenManager.addScene(scene);
  scenenManager.setCameraToScene(scene1,camera)
  scenenManager.setControlsToScene(scene1,controls)
  scenenManager.setRendererToScene(scene1,renderer)
  scene1Manager({
    type:'init',
    listenMeshes: [...china.userData.listenMesh],
    mesh: china
  });
}

/**
 * @description: 初始化场景2
 */
async function initScene2(){
  let renderer = UseCreateRenderer(document.querySelector(".map"));
  let camera = UseCreateCamera(document.querySelector(".map"))
  let controls = UseCreateControls(camera,renderer);
  let scene = UseCreateScene();
  let sichuan = await UseCreateArea(510000,'四川',[104.065735, 30.659462]);
  scene.add(sichuan);
  scene2 = scenenManager.addScene(scene);
  scenenManager.setCameraToScene(scene2,camera)
  scenenManager.setControlsToScene(scene2,controls)
  scenenManager.setRendererToScene(scene2,renderer)
}

/**
 * @description: 初始化场景
 * @returns {Promise<void>}
 */
async function iniScene(){
  await initScene1();
  initScene2();
  scenenManager.setCurrentSceneByName(scene1);
  animate();
  UseCreateGUIHelp()
}

/**
 * @description: 场景1管理
 * @param option{type:'go',listenMeshes:[],mesh:Object3D}
 */
 async  function scene1Manager(option){
    // let defaultOpt = {
    //    type: 'go',// back , init
    // }
    let scene = scenenManager.getScene(scene1);
    switch (option.type){
      case 'go':
      case 'back':
        scene.userData.listenMesh = option.listenMeshes;
        scene.remove(scene.userData.mapStack[scene.userData.mapStack.length - 1]);
        if(option.type === 'go'){
          scene.userData.mapStack.push(option.mesh);
          menus.value.push({
            name: option.mesh.name,
            code: option.mesh.adcode,
            centroid:option.mesh.centroid
          });
          scene.add(option.mesh)
          break
        }
        scene.userData.mapStack.pop(option.mesh);
        menus.value.pop({
          name: option.mesh.name,
          code: option.mesh.adcode,
          centroid:option.mesh.centroid
        })
        scene.add(option.mesh);
        break;
      case 'init':
        scene.userData.listenMesh = option.listenMeshes;
        scene.userData.mapStack = [option.mesh];
        menus.value.push({
          name: '中国',
          code: 10000,
          centroid: [114.298572, 30.584355]
        })
        break;
      case 'menu':
        //点击菜单
          scene.remove(scene.userData.mapStack[scene.userData.mapStack.length - 1]);
          let code = option.menu.code;
          let name = option.menu.name;
          let center = option.menu.centroid;
          console.log("climenu",center)
          let mesh = await UseCreateArea(code,name,center);
          scene.add(mesh);
          scene.userData.listenMesh = mesh.userData.listenMesh;
          scene.userData.mapStack = scene.userData.mapStack.splice(0,option.index + 1);
          scene.userData.mapStack[scene.userData.mapStack.length - 1] = mesh; //更新栈顶
          menus.value = menus.value.splice(0,option.index + 1);
          break;
    }

}

/**
 * @description: 动画
 */
function animate(){
  scenenManager.getCurrentSceneControls().update();
  scenenManager.getCurrentSceneCamera().updateProjectionMatrix();
  scenenManager.getCurrentSceneRenderer().render(scenenManager.getCurrentScene(),scenenManager.getCurrentSceneCamera());
  requestAnimationFrame(animate);
}

/**
 * @description: 切换场景
 */
function changeScene(){
  scene1 ===  scenenManager.getCurrentSceneName() ? scenenManager.setCurrentSceneByName(scene2): scenenManager.setCurrentSceneByName(scene1);
}

/**
 * @description: 点击地图事件
 * @param $event
 */
 function onClickMap($event){
   showMenu.value = false;
  if($event.detail === 2 && scenenManager.getCurrentSceneName() === scene1){
    //场景1且是双击
    let scene = scenenManager.getScene(scene1);
    let camera = scenenManager.getCamera(scene1);
    UseCreateRaycaster($event,camera,scene.userData.listenMesh,listenDom,async currentActive=>{
      if(currentActive?.length === 0){
        return;
      }
      let code = currentActive[0].object.adcode;
      let name = currentActive[0].object.name;
      let centroid = currentActive[0].object.centroid;
      let newMap = await UseCreateArea(code,name,centroid);
      scene1Manager({
        type:'go',
        listenMeshes: [...newMap.userData.listenMesh],
        mesh: newMap
      })
    });
  }


}
 function onClickMenu(menu,index){
   scene1Manager({
     type: 'menu',
     menu,
     index
   })
}

</script>
<style lang="css" scoped>
ul,li{
  list-style: none;
  padding: 0;
  margin: 0;
  border: none;
}
.map{
  width: 100%;
  height: 100%;
}

.btn {
  width: 40px;
  height: 40px;
  cursor: pointer;
}
.menus{
  display: none;
  position: absolute;
  background: #f2f2f2;
  color: #222222;
  border-radius: 4px;
}
.menus ul{
  display: flex;
  flex-direction: row;
  padding: 10px 10px;
}
.menus ul li{
  cursor: pointer;

}
.menus ul li:hover{
  color: #21c4df;
}
.show-menu.menus{
  display: block;
}
.a-menu:not(:last-child)::after{
  content: "/";
  padding: 0px 2px;
  display: inline-block;

}
.active-menu{
  color: #21c4df;
  cursor: not-allowed;
  pointer-events: none;
}
</style>